package com.naiterui.ehp.bs.ds.modules.sys.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Preconditions;
import com.naiterui.ehp.bs.ds.common.constants.CacheConstants;
import com.naiterui.ehp.bs.ds.common.utils.PageVO;
import com.naiterui.ehp.bs.ds.common.vo.PageParamsVO;
import com.naiterui.ehp.bs.ds.modules.sys.entity.Dept;
import com.naiterui.ehp.bs.ds.modules.sys.entity.Role;
import com.naiterui.ehp.bs.ds.modules.sys.mapper.RoleMapper;
import com.naiterui.ehp.bs.ds.modules.sys.service.IDeptService;
import com.naiterui.ehp.bs.ds.modules.sys.service.IRoleDeptService;
import com.naiterui.ehp.bs.ds.modules.sys.service.IRoleMenuService;
import com.naiterui.ehp.bs.ds.modules.sys.service.IRoleService;
import com.naiterui.ehp.bs.ds.modules.sys.service.IUserRoleService;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 角色
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {

    @Autowired
    private IRoleMenuService roleMenuService;
    @Autowired
    private IRoleDeptService roleDeptService;
    @Autowired
    private IUserRoleService userRoleService;
    @Autowired
    private IDeptService deptService;

    @Override
    public Role getRoleInfo(Long roleId) {
        Role role = super.getById(roleId);
        // 查询角色对应的菜单
        List<Long> menuIdList = this.roleMenuService.queryMenuIdList(roleId);
        role.setMenuIdList(menuIdList);
        return role;
    }

    @Override
    public PageVO<Role> queryPage(PageParamsVO pageParamsVO, Role role) {
        IPage<Role> page = this.page(pageParamsVO.getPage(), pageParamsVO.getEntityWrapper(role));
        page.getRecords().forEach(entity -> {
            Dept dept = this.deptService.getById(entity.getDeptId());
            if (dept != null) {
                entity.setDeptName(dept.getName());
            }
        });
        return PageVO.toPageVo(page);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean save(Role role) {
        boolean save = super.save(role);
        // 保存角色与菜单关系
        this.roleMenuService.saveOrUpdate(role.getId(), role.getMenuIdList());
        return save;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = {CacheConstants.MENU_LIST, CacheConstants.USER_MENU_LIST, CacheConstants.USER,
        CacheConstants.PERMISSION_CACHE_PREFIX}, allEntries = true)
    public void update(Role role) {
        Long id = role.getId();
        Preconditions.checkNotNull(id, "角色ID不能为null");
        // 如果修改了部门部门，那么要清空
        Long deptId = this.baseMapper.getDeptIdById(id);
        if (!Objects.equals(deptId, role.getDeptId())) {
            // 删除角色与用户关联
            this.userRoleService.deleteBatch(new Long[]{id});
        }
        super.updateById(role);
        // 更新角色与菜单关系
        this.roleMenuService.saveOrUpdate(id, role.getMenuIdList());

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = {CacheConstants.MENU_LIST, CacheConstants.USER_MENU_LIST, CacheConstants.USER,
        CacheConstants.PERMISSION_CACHE_PREFIX}, allEntries = true)
    public void deleteBatch(Long[] roleIds) {
        // 删除角色
        super.removeByIds(Arrays.asList(roleIds));
        // 删除角色与菜单关联
        this.roleMenuService.deleteBatch(roleIds);
        // 删除角色与部门关联
        this.roleDeptService.deleteBatch(roleIds);
        // 删除角色与用户关联
        this.userRoleService.deleteBatch(roleIds);
    }

    @Override
    public List<Role> selectBatchIds(List<Long> roleIdList) {
        return this.baseMapper.selectBatchIds(roleIdList);
    }

}
